package com.stable.spider.eastmoney;

import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.stable.utils.HtmlunitSpider;
import com.stable.vo.spi.req.FundInterestGp;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@Log4j2
public class FundHoldGpSpider {

    //<code,List<FundInterestGp>>
    static Cache<String, List<FundInterestGp>> cacheFundInterestGp = CacheBuilder.newBuilder()
            .expireAfterWrite(300, TimeUnit.MINUTES)
            .maximumSize(100)
            .build();

    /**
     * 根据基金code获取持仓的前10大股票
     *
     * @param fundCode
     * @return http://fundf10.eastmoney.com/ccmx_005827.html
     */
    public static List<FundInterestGp> getFundInterestGp(String fundCode) {
        List<FundInterestGp> getCache = cacheFundInterestGp.getIfPresent(fundCode);
        if (getCache == null || getCache.size() == 0) {
            HtmlunitSpider htmlunitSpider = new HtmlunitSpider();
            HtmlPage htmlPageFromUrl = htmlunitSpider.getHtmlPageFromUrl("http://fundf10.eastmoney.com/ccmx_" + fundCode + ".html");
            HtmlElement body = htmlPageFromUrl.getBody();
            List<HtmlElement> elementsByAttribute = body.getElementsByAttribute("table", "class", "w782 comm tzxq");

            List list = new ArrayList();
            try {
                List<HtmlElement> tbody = elementsByAttribute.get(0).getElementsByAttribute("tbody", "", "");
                List<HtmlElement> tr = tbody.get(0).getElementsByAttribute("tr", "", "");

                for (int i = 0; i < tr.size(); i++) {
                    Iterator<DomElement> iterator = tr.get(i).getChildElements().iterator();
                    FundInterestGp fundInterestGp = new FundInterestGp();
                    int index = 0;
                    while (iterator.hasNext()) {
                        DomElement next = iterator.next();
                        //持仓序号
                        if (index == 0) {
                            fundInterestGp.setJjcode(fundCode);
                            fundInterestGp.setOrder(next.asText());
                        }
                        //股票代码
                        if (index == 1) {
                            fundInterestGp.setCode(next.asText());
                        }
                        //股票名称
                        if (index == 2) {
                            fundInterestGp.setName(next.asText());
                        }
                        //持仓占比
                        if (index == 6) {
                            fundInterestGp.setZhanbi(next.asText());
                            list.add(fundInterestGp);
                        }
                        index++;
                    }
                }
                return list;
            } catch (RuntimeException e) {
                log.error("基金代码：{} 获取数据失败", fundCode);
                return list;
            }
        } else {
            return getCache;
        }
    }

    public static void main(String[] args) {
        List listAll = new ArrayList();
//        listAll.addAll(FundHoldGpSpider.getFundInterestGp("160133"));
//        listAll.addAll(FundHoldGpSpider.getFundInterestGp("005827"));
//        listAll.addAll(FundHoldGpSpider.getFundInterestGp("007119"));
//        listAll.addAll(FundHoldGpSpider.getFundInterestGp("007968"));
        listAll.add(new FundInterestGp("jj003", "gp001", "股票1"));
        listAll.add(new FundInterestGp("jj001", "gp001", "股票1"));
        listAll.add(new FundInterestGp("jj001", "gp002", "股票2"));
        listAll.add(new FundInterestGp("jj001", "gp003", "股票3"));
        listAll.add(new FundInterestGp("jj001", "gp004", "股票4"));
        listAll.add(new FundInterestGp("jj001", "gp005", "股票5"));
        listAll.add(new FundInterestGp("jj002", "gp001", "股票1"));
        listAll.add(new FundInterestGp("jj002", "gp002", "股票2"));
        listAll.add(new FundInterestGp("jj002", "gp003", "股票3"));
        Map<String,ArrayList<FundInterestGp>> map = (Map) listAll.stream().collect(Collectors.groupingBy(FundInterestGp::getName, LinkedHashMap::new, Collectors.toList()));
//        Map<String,ArrayList> map = (Map) listAll.stream().collect(Collectors.groupingBy(FundInterestGp::getName, Collectors.counting()));

        map.entrySet().stream().forEach(x -> {
            StringBuilder builder = new StringBuilder();
            x.getValue().forEach(y->{
                builder.append(y.getJjcode()+",");
            });
            System.out.println(x.getKey()+"|"+x.getValue().size() +"|"+ builder.toString());
        });
        System.out.println();
//        map.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).forEach(x ->{
//            System.out.println(x);
//        });


//        //1.分组计数
//        List<Student> list1= Arrays.asList(
//                new Student(1,"one","zhao"),new Student(2,"one","qian"),new Student(3,"two","sun"));
//        //1.1根据某个属性分组计数
//        Map<String,Long> result1=list1.stream().collect(Collectors.groupingBy(Student::getGroupId,Collectors.counting()));
//        System.out.println(result1);
//        //1.2根据整个实体对象分组计数,当其为String时常使用
//        Map<Student,Long> result2=list1.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
//        System.out.println(result2);
//        //1.3根据分组的key值对结果进行排序、放进另一个map中并输出
//        Map<String,Long> xMap=new HashMap<>();
//        result1.entrySet().stream().sorted(Map.Entry.<String,Long>comparingByKey().reversed()) //reversed不生效
//                .forEachOrdered(x->xMap.put(x.getKey(),x.getValue()));
//        System.out.println(xMap);
//
//        //2.分组，并统计其中一个属性值得sum或者avg:id总和
//        Map<String,Integer> result3=list1.stream().collect(
//                Collectors.groupingBy(Student::getGroupId,Collectors.summingInt(Student::getId))
//        );
//        System.out.println(result3);
    }
}
